<template>
	<div>
		<uoloadExcel :on-success="handleSuccess" :before-upload="beforeUpload"></uoloadExcel>
		<el-table :data="state.tableData" border highlight-current-row style="width: 100%; margin-top: 20px">
			<el-table-column v-for="item of state.tableHeader" :key="item" :prop="item" :label="item" />
		</el-table>
	</div>
</template>
<script lang="ts" setup name="ImportExcel">
import uoloadExcel from './upload-excel.vue';
import { httpReqeustApi } from '/@/api/linxyun/base/index.ts';
import EnumOptions from '/@/components/Linxyun/Datas/enum_options.js';
import Lxy_page_event_remote from '/@/components/Linxyun/custom/CustomCommon/lxy_page_event_remote.js';
import { treeData2Optioins } from '/@/components/Linxyun/custom/CustomCommon/tools.js';
import { getVuex } from '/@/utils/formatPrivacyData.js';
import { ElMessage } from 'element-plus';
const httpRequest = httpReqeustApi();

const props = withDefaults(
	defineProps<{
		// 导入配置
		importDefine: Record<string, any>;
		// 页面配置
		pageDefines: Record<string, any>;
	}>(),
	{
		importDefine: () => ({}),
		pageDefines: () => ({}),
	}
);

const emit = defineEmits(['clone']);
const state = reactive<{
	tableData: any[];
	tableHeader: any[];
	pageDefine: any[];
	queryUrl: any[];
	enumOrSelect: Record<string, any>;
}>({
	tableData: [], // 表格数据
	tableHeader: [], // 表格头
	pageDefine: [], // 接收页面配置中为下拉选择/枚举的字段
	queryUrl: [], // 用来查询配置为下拉选择的字段的关联表接口
	enumOrSelect: {}, // 存放excel中和页面配置相对应的下拉选择/枚举字段及其内容
});

// 获取表单中定义为下拉选择、下拉枚举、级联选择的字段
state.pageDefine =
	props.pageDefines.FieldDefines.filter(
		(item) => item.InputType === 'el-cascader' || item.InputType === 'select_d' || item.InputType === 'el-select'
	) || [];

const beforeUpload = (file) => {
	const isLt1M = file.size / 1024 / 1024 < 1;
	if (isLt1M) {
		return true;
	}
	ElMessage({
		message: '请不要导入大小超过1m的文件。',
		type: 'warning',
	});
	return false;
};

const handleSuccess = ({ results, header }: Record<string, any>) => {
	state.tableData = results;
	state.tableHeader = header;
	/*
				导入的excel列是否配置为需要导入，如果是则把对应的excel列名转换成字段名放到params里
				并把配置为下拉选择/下拉枚举对应值的字段提取出来
			*/
	const vuexValue: any[] = []; // 保存获取的vuex值
	state.tableHeader.forEach((item, i) => {
		props.importDefine.eventData.forEach((data) => {
			if (data.dataType === '5') {
				vuexValue.push({ key: data.value, value: getVuex(data.Number) });
			} else if (createCol(i) === data.Number) {
				state.tableData.forEach((val) => {
					for (const key in val) {
						if (item === key) {
							if (!val['params']) {
								val['params'] = {};
							}
							val['params'][data.value] = val[key];
							if (data.dataType === '2') {
								!val._enume ? (val._enume = []) : '';
								val._enume.push(data.value);
							}
							if (data.dataType === '3') {
								!val._select ? (val._select = []) : '';
								val._select.push(data.value);
							}
							if (data.dataType === '4') {
								!val._cascde ? (val._cascde = []) : '';
								val._cascde.push(data.value);
							}
						}
					}
				});
			}
		});
	});
	// 把获取到的vuex值存进要导入的行数据中
	vuexValue.forEach((item) => {
		state.tableData.forEach((tab) => {
			tab.params[item.key] = item.value;
		});
	});
	extractField();
	console.log('tableData', state.tableData);
};

// 导入的excel中是否有表单配置下拉选择/枚举/级联字段，如果有，则把字段提取放到enumOrSelect中以便后边转换
const extractField = () => {
	console.log('pageDefine', state.pageDefine);
	for (const key in state.tableData[0].params) {
		state.pageDefine.forEach((item) => {
			console.log('itemitem', item);
			if (item.FieldName === key) {
				console.log('extractField', item);
				const type = item.InputType === 'el-cascader' ? 'cascade' : item.InputType === 'select_d' ? 'select' : 'enume';
				if (item.InputType === 'el-cascader') {
					!state.enumOrSelect['cascade'] ? (state.enumOrSelect['cascade'] = {}) : '';
					!state.enumOrSelect.cascade.Records ? (state.enumOrSelect.cascade.Records = {}) : '';
					!state.enumOrSelect.cascade.Records[item.FieldName] ? (state.enumOrSelect.cascade.Records[item.FieldName] = {}) : '';
					queryCascdeTree(item);
				} else if (item.InputType === 'select_d') {
					state.queryUrl.push({ type: type, url: item.InputDefine.event.url, params: item.InputDefine.params });

					console.log(state.queryUrl);
					if (!state.enumOrSelect['select']) {
						state.enumOrSelect['select'] = {};
					}
					state.enumOrSelect.select[item.InputDefine.inputflag] = item.InputDefine.inputdisplay;
					queryRelevantTab(item.InputDefine.inputflag);
				} else {
					if (!state.enumOrSelect['enum']) {
						state.enumOrSelect['enum'] = {};
					}

					state.enumOrSelect.enum[item.FieldName] = item.InputDefine.EnumValue;
					queryRelevantEnum(item.FieldName);
				}
			}
		});
	}
};

// 查询下拉选择字段关联表数据
const queryRelevantTab = (val) => {
	if (state.queryUrl.length) {
		state.queryUrl.forEach((item) => {
			httpRequest.Post(item.url, item.params).then((res) => {
				if (res.success && res.code === '0000') {
					!state.enumOrSelect.select.Records ? (state.enumOrSelect.select.Records = {}) : '';
					state.enumOrSelect.select.Records[val] = res.Records || [];
				}
			});
		});
	}
};
// 查询下拉枚举字段关联枚举定义数据
const queryRelevantEnum = (value) => {
	if (state.enumOrSelect['enum']) {
		for (const key in state.enumOrSelect.enum) {
			!state.enumOrSelect.enum.Records ? (state.enumOrSelect.enum.Records = {}) : '';
			state.enumOrSelect.enum.Records[value] = EnumOptions.instance().getOptions(state.enumOrSelect.enum[key]);
		}
	}
};
// 获取级联树节点
const queryCascdeTree = async (item) => {
	if (!item.inputDefine || !item.inputDefine.event || !item.inputDefine.event.url) {
		console.error('[Error][cascader]Not define url: ', item.FieldName);
		return;
	}
	const remoteEvent = new Lxy_page_event_remote(item.inputDefine.event);
	remoteEvent.setDataSrc(this.pageData, this.inputData);
	const result = await remoteEvent.callEvent(null);
	if (!result || !result.data) {
		console.error('[Error]call remote method fail, itme: ', item.FieldName);
	}
	item.doptions.splice(0, item.doptions.length);
	treeData2Optioins(result.data.Child, item.doptions);
	if (item.doptions) {
		item.doptions.splice(0, 0);
	}
	state.enumOrSelect.cascade.Records[item.value] = item.doptions;
	console.log('[Debug][Form][cascader] doptions: ', item.doptions);
};

const getCascaderDataArray = (doptions, value, resultArray) => {
	if (!doptions || doptions.length === 0) {
		return;
	}

	for (let i = 0; i < doptions.length; i++) {
		if (value && value.indexOf(doptions[i].value) === 0) {
			resultArray.push(doptions[i].value);
			if (doptions[i].children && doptions[i].children.length > 0) {
				getCascaderDataArray(doptions[i].children, value, resultArray);
			}
		}
	}
};

// 把数字转换为Excel中对应的列序号
const createCol = (n) => {
	const ordA = 'A'.charCodeAt(0);
	const ordZ = 'Z'.charCodeAt(0);
	const len = ordZ - ordA + 1;
	let str = '';
	while (n >= 0) {
		str = String.fromCharCode((n % len) + ordA) + str;
		n = Math.floor(n / len) - 1;
	}
	return str;
};
const importData = () => {
	const proAll: any = [];
	const Data = state.tableData.slice(props.importDefine.startRow - 1);
	console.log('importData', Data);
	Data.forEach((item, i) => {
		if (item._select) {
			transSelect(item);
		}
		if (item._enume) {
			transEnum(item);
		}
		if (item._cascde) {
			transCascde(item);
		}
		proAll[i] = new Promise((resolve) => {
			httpRequest.Post(props.importDefine.interface, null, item.params).then((res: any) => {
				resolve(res);
			});
		});
	});
	Promise.all(proAll).then((res) => {
		if (res.every((item) => item.success && item.code === '0000')) {
			ElMessage({
				message: '导入成功',
				type: 'success',
			});
			emit('clone');
		} else if (res.find((item) => !item.success || item.code !== '0000')) {
			res.forEach((item, i) => {
				if (!item.success || item.code !== '0000') {
					ElMessage({
						message: '第' + (i + 1) + '行数据导入出错',
						type: 'error',
					});
				}
			});
		}
	});
};

// 把表格里的显示值转换成对应的下拉选择值
const transSelect = (data) => {
	for (let selVal of data._select) {
		for (const key in state.enumOrSelect.select.Records) {
			if (key === selVal) {
				state.enumOrSelect.select.Records[key].forEach((item) => {
					if (item[state.enumOrSelect.select[selVal]] === data.params[selVal]) {
						data.params[selVal] = item[key];
					}
				});
			}
		}
	}
};
// 把表格里的显示值转换成对应的下拉枚举值
const transEnum = (data) => {
	console.log('transEnum', data);
	console.log('enumOrSelect', state.enumOrSelect);
	for (let enumVal of data._enume) {
		for (const enumKey in state.enumOrSelect.enum.Records) {
			if (enumKey === enumVal) {
				state.enumOrSelect.enum.Records[enumKey].forEach((item) => {
					if (data.params[enumVal] === item.label) {
						data.params[enumVal] = item.value;
					}
				});
			}
		}
	}
};
// 把匹配的树节点实际值赋值到对应的行字段中
const transCascde = (data) => {
	for (let casVal of data._cascde) {
		for (const cascdeKey in state.enumOrSelect.cascade.Records) {
			if (cascdeKey === casVal) {
				data.params[casVal] = getCascdeValue(state.enumOrSelect.cascade.Records[cascdeKey], data.params[casVal]);
			}
		}
	}
};
// 递归匹配树节点
const getCascdeValue = (tree, value) => {
	let treeValue: any;
	for (let i = 0; i < tree.length; i++) {
		if (tree[i].children && tree[i].children.length && value !== tree[i].label) {
			treeValue = getCascdeValue(tree[i].children, value);
			if (treeValue) {
				return treeValue;
			}
		} else if (tree[i].label === value) {
			treeValue = tree[i].value;
			break;
		}
	}
	return treeValue;
};

defineExpose({
	importData,
});
</script>

<style lang="scss" scoped></style>
